//  IDVI 1.0 source copyright 1996 Garth A. Dickie
//
//  This source is free for non-commercial use.  No warranty, etc.
//  Please acknowledge reuse by including the line:
//
//  "Based in part on IDVI 1.0 source copyright 1996 Garth A. Dickie"
//
//  in your documentation and source code.  For commercial use or
//  distribution, please contact the author.  Please also send
//  questions, comments, bug reports, or fixes.
//
//  Best Regards,
//  Garth A. Dickie
//  dickie@elastic.avid.com

package ibook.v10.idvi.display;

import java.util.Hashtable;

//  The ColorScheme class contains information about a set of colors to
//  be used in displaying a DVI file.  Most of the relevant information
//  is actually stored in a ScaledColorScheme object, since ColorModel
//  and ScaledCharacter objects depend on the scale factor.

public final class ColorScheme {
    //  static methods and variables:
    //
    //  A ColorScheme object is never constructed directly.  Instead, a
    //  ColorScheme object is obtained using the getColorScheme( ) methods.
    //  The ColorScheme class keeps a Hashtable of ColorScheme objects,
    //  and returns a previously-created ColorScheme object if possible.
    //
    //  A ColorScheme object is used to index the hashtable.  If an existing
    //  ColorScheme with the same colors is found, that ColorScheme is returned.
    //  Otherwise, the key is inserted into the hashtable (and returned), and
    //  a new key is created for use in the next request.

    final private static int    cacheInitialSize = 5;   // often only 1...

    private static Hashtable    cache = new Hashtable( cacheInitialSize );
    private static ColorScheme  key = new ColorScheme( );

    public static synchronized ColorScheme getColorScheme(
            int background,
            int foreground,
            int selection,
            int link,
            int selectedLink ) {
        
        key.background   = background;
        key.foreground   = foreground;
        key.selection    = selection;
        key.link         = link;
        key.selectedLink = selectedLink;

        ColorScheme result = ( ColorScheme ) cache.get( key );

        if( result == null ) {
            result = key;
            cache.put( key, key );
            key = new ColorScheme( );
        }

        return result;
    }

    public static ColorScheme getColorScheme( 
            ColorScheme base,
            int foreground ) {

        return getColorScheme( base.background, foreground, base.selection, foreground, base.selectedLink );
    }




    //  instance methods and variables:

    private int     background;
    private int     foreground;
    private int     selection;
    private int     link;
    private int     selectedLink;

    private ColorScheme( ) {
    }

    //  A ColorScheme object can't do very much.  Instead, a ScaledColorScheme
    //  is used to manage ColorModel objects and a cache of Color objects. So
    //  the main purpose of a ColorScheme object is to answer getScaledColorScheme( )
    //  requests.  And in fact, it just passes these to a static method of the
    //  ScaledColorScheme class.  So a ColorScheme is really just a holder for
    //  a set of colors, with the property that two ColorScheme objects which
    //  are distinct are also not equal( ).

    public ScaledColorScheme getScaledColorScheme( int scale ) {
        return ScaledColorScheme.getScaledColorScheme(
            this, scale, background, foreground, selection, link, selectedLink );
    }

    //  The hashCode( ) and equals( ) methods are used in the getColorScheme( )
    //  Hashtable lookups.

    public int hashCode( ) {
        return background ^ foreground ^ selection ^ link ^ selectedLink;
    }

    public boolean equals( Object object ) {
        return object instanceof ColorScheme && equals(( ColorScheme ) object );
    }

    public boolean equals( ColorScheme key ) {
        return
            background   == key.background &&
            foreground   == key.foreground &&
            selection    == key.selection  &&
            link         == key.link       &&
            selectedLink == key.selectedLink;
    }
}
